#include "MyFunction.h"

volatile dynamic_callback dyc_cbk_exti0_IRQ_hdr[7]={0};
char *myStrdup(const char *s) {
		size_t len = strlen(s) + 1;
    char *copy = malloc(len);
    if (s == NULL) return NULL;
    if (copy) memcpy(copy, s, len);
    return copy;
}
char *myStrsep(char *curr_p, const char *delim,char **next_p) {
	char *end = curr_p + strcspn(curr_p, delim); 
	//printf("myStrsep %s\r\n",curr_p);
	if (*curr_p == '\0') {return *next_p = NULL;}
	*end = '\0';
	*next_p = end + 1;
	return curr_p;
}
void gpioInit(char *str){
	GPIO_InitTypeDef  GPIO_InitStructure;
	char *endptr_str,*gpio_x;
	u8 pin_x_i,gpio_mode_i;
	gpio_x = myStrsep(str, "|",&str);
	pin_x_i = strtol(gpio_x + 1, &endptr_str, 10);
	gpio_mode_i = strtol(str, &endptr_str, 10);
	printf("gpioInit|%s|%d\r\n",gpio_x,gpio_mode_i);
	GPIO_InitStructure.GPIO_Pin = gpio_pin_cb[pin_x_i];
	GPIO_InitStructure.GPIO_Mode = (GPIOMode_TypeDef)gpio_mode_cb[gpio_mode_i];
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHz
		
		//使能端口时钟//根据设定参数初始化GPIO
	if('A'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_Init(GPIOA, &GPIO_InitStructure);}
	if('B'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_Init(GPIOB, &GPIO_InitStructure);}
	if('C'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_Init(GPIOC, &GPIO_InitStructure);}
	if('D'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);GPIO_Init(GPIOD, &GPIO_InitStructure);}
	if('E'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);GPIO_Init(GPIOE, &GPIO_InitStructure);}
	if('F'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);GPIO_Init(GPIOF, &GPIO_InitStructure);}
	if('G'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);GPIO_Init(GPIOG, &GPIO_InitStructure);}
}
void gpioOutHigh(char *xb){
	char *endptr_str;
	u8 pin_x_i = strtol(xb + 1, &endptr_str, 10);
	printf("gpioOutHigh|%s\r\n",xb);
	if('A'==xb[0]){GPIO_SetBits(GPIOA,gpio_pin_cb[pin_x_i]);}
	if('B'==xb[0]){GPIO_SetBits(GPIOB,gpio_pin_cb[pin_x_i]);}
	if('C'==xb[0]){GPIO_SetBits(GPIOC,gpio_pin_cb[pin_x_i]);}
	if('D'==xb[0]){GPIO_SetBits(GPIOD,gpio_pin_cb[pin_x_i]);}
	if('E'==xb[0]){GPIO_SetBits(GPIOE,gpio_pin_cb[pin_x_i]);}
	if('F'==xb[0]){GPIO_SetBits(GPIOF,gpio_pin_cb[pin_x_i]);}
	if('G'==xb[0]){GPIO_SetBits(GPIOG,gpio_pin_cb[pin_x_i]);}
}
void gpioOutlow(char *xb){
	char *endptr_str;
	u8 pin_x_i = strtol(xb + 1, &endptr_str, 10);
	printf("gpioOutlow|%s\r\n",xb);
	if('A'==xb[0]){GPIO_ResetBits(GPIOA,gpio_pin_cb[pin_x_i]);}
	if('B'==xb[0]){GPIO_ResetBits(GPIOB,gpio_pin_cb[pin_x_i]);}
	if('C'==xb[0]){GPIO_ResetBits(GPIOC,gpio_pin_cb[pin_x_i]);}
	if('D'==xb[0]){GPIO_ResetBits(GPIOD,gpio_pin_cb[pin_x_i]);}
	if('E'==xb[0]){GPIO_ResetBits(GPIOE,gpio_pin_cb[pin_x_i]);}
	if('F'==xb[0]){GPIO_ResetBits(GPIOF,gpio_pin_cb[pin_x_i]);}
	if('G'==xb[0]){GPIO_ResetBits(GPIOG,gpio_pin_cb[pin_x_i]);}
}
void delayMs(char *xb){
		char *endptr_str;
    unsigned long seconds = strtoul(xb, &endptr_str, 10);   
    if (endptr_str == xb || *endptr_str != '\0' || seconds == 0 || seconds > 1000) {
        printf("delayMs Invalid input! Use 1-1000 \r\n");
        return;
    }
		delay_ms(seconds);
}
 
void IRQconfig(char *str){
	GPIO_InitTypeDef GPIO_InitStruct;
	EXTI_InitTypeDef EXTI_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	 
	char *endptr_str;
	char *gpio_x = myStrsep(str, "|",&str);
	u8 pin_x_i = strtol(gpio_x + 1, &endptr_str, 10);
	u8 gpio_mode_i = strtol(myStrsep(str, "|",&str), &endptr_str, 10);
	u32 exti_line_i = strtol(myStrsep(str, "|",&str), &endptr_str, 10);
	u8 exti_x_irqn_i = strtol(myStrsep(str, "|",&str), &endptr_str, 10);
	u8 exti_trigger_i = strtol(myStrsep(str, "|",&str), &endptr_str, 10);
	unsigned int function_addr = strtol(myStrsep(str, "|",&str), &endptr_str, 10);
	char buffer[32]; // 确保足够大
	snprintf(buffer, sizeof(buffer), "%d|%s", exti_line_i,str);
	//char *op_gpio_x = str;
	printf("IRQconfig S|%s|%d|%d|%d|%d|%d|%s\r\n",gpio_x,gpio_mode_i,exti_line_i,exti_x_irqn_i,exti_trigger_i,function_addr,str);
	GPIO_InitStruct.GPIO_Pin = gpio_pin_cb[pin_x_i];
	GPIO_InitStruct.GPIO_Mode = (GPIOMode_TypeDef)gpio_mode_cb[gpio_mode_i];
	if('A'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource[pin_x_i]);}
	if('B'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);GPIO_Init(GPIOB, &GPIO_InitStruct);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource[pin_x_i]);}
	if('C'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);GPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource[pin_x_i]);}
	if('D'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);GPIO_Init(GPIOD, &GPIO_InitStruct);GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource[pin_x_i]);}
	if('E'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);GPIO_Init(GPIOE, &GPIO_InitStruct);GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource[pin_x_i]);}
	if('F'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF | RCC_APB2Periph_AFIO, ENABLE);GPIO_Init(GPIOF, &GPIO_InitStruct);GPIO_EXTILineConfig(GPIO_PortSourceGPIOF, GPIO_PinSource[pin_x_i]);}
	if('G'==gpio_x[0]){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG | RCC_APB2Periph_AFIO, ENABLE);GPIO_Init(GPIOG, &GPIO_InitStruct);GPIO_EXTILineConfig(GPIO_PortSourceGPIOG, GPIO_PinSource[pin_x_i]);}	 
	/*为中断配置中断服务程序*/
	if(0==pin_x_i){dyc_cbk_exti0_IRQ_hdr[0].callback = (void (*)(char *))function_addr;dyc_cbk_exti0_IRQ_hdr[0].param = str;}
	if(1==pin_x_i){dyc_cbk_exti0_IRQ_hdr[1].callback = (void (*)(char *))function_addr;dyc_cbk_exti0_IRQ_hdr[1].param = str;}
	if(2==pin_x_i){dyc_cbk_exti0_IRQ_hdr[2].callback = (void (*)(char *))function_addr;dyc_cbk_exti0_IRQ_hdr[2].param = str;}
	if(3==pin_x_i){dyc_cbk_exti0_IRQ_hdr[3].callback = (void (*)(char *))function_addr;dyc_cbk_exti0_IRQ_hdr[3].param = str;}
	if(4==pin_x_i){dyc_cbk_exti0_IRQ_hdr[4].callback = (void (*)(char *))function_addr;dyc_cbk_exti0_IRQ_hdr[4].param = str;}
	if(4<pin_x_i&&pin_x_i<10){dyc_cbk_exti0_IRQ_hdr[5].callback = (void (*)(char *))function_addr;dyc_cbk_exti0_IRQ_hdr[5].param=myStrdup(buffer);}
	if(9<pin_x_i){dyc_cbk_exti0_IRQ_hdr[6].callback = (void (*)(char *))function_addr;dyc_cbk_exti0_IRQ_hdr[6].param=myStrdup(buffer);}
	EXTI_InitStruct.EXTI_Line = exti_line[exti_line_i];
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger = (EXTITrigger_TypeDef)EXTITriggerTypeDef[exti_trigger_i];// 4. 配置EXTI0为上升沿触发
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStruct);
   
	NVIC_InitStruct.NVIC_IRQChannel = exti_x_irqn[exti_x_irqn_i];//EXTI0_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);
	printf("IRQconfig E\r\n");
	
}
void EXTI0_IRQHandler(void){
	if (EXTI_GetITStatus(EXTI_Line0)) {
		EXTI->IMR &= ~EXTI_Line0;
		EXTI_ClearITPendingBit(EXTI_Line0);
		if (dyc_cbk_exti0_IRQ_hdr[0].callback != NULL) {
			dyc_cbk_exti0_IRQ_hdr[0].callback(dyc_cbk_exti0_IRQ_hdr[0].param); // 调用回调函数并传递参数
			//printf("EXTI0_IRQHandler\r\n");
    }
  }
}


void EXTI1_IRQHandler(void){
	if (EXTI_GetITStatus(EXTI_Line1)) {	
		EXTI->IMR &= ~EXTI_Line1;
		EXTI_ClearITPendingBit(EXTI_Line1);
		if (dyc_cbk_exti0_IRQ_hdr[1].callback != NULL) {
			//printf("EXTI1_IRQHandler\r\n");
			dyc_cbk_exti0_IRQ_hdr[1].callback(dyc_cbk_exti0_IRQ_hdr[1].param); // 调用回调函数并传递参数
    }
  }
}
void EXTI2_IRQHandler(void){
	if (EXTI_GetITStatus(EXTI_Line2)) {
		EXTI->IMR &= ~EXTI_Line2;
		EXTI_ClearITPendingBit(EXTI_Line2);
		if (dyc_cbk_exti0_IRQ_hdr[2].callback != NULL) {
			//printf("EXTI2_IRQHandler\r\n");
			dyc_cbk_exti0_IRQ_hdr[2].callback(dyc_cbk_exti0_IRQ_hdr[2].param); // 调用回调函数并传递参数
    }
  }
}
void EXTI3_IRQHandler(void){
	if (EXTI_GetITStatus(EXTI_Line3)) {
		EXTI->IMR &= ~EXTI_Line3;
		EXTI_ClearITPendingBit(EXTI_Line3);
		if (dyc_cbk_exti0_IRQ_hdr[3].callback != NULL) {
			//printf("EXTI3_IRQHandler\r\n");
			dyc_cbk_exti0_IRQ_hdr[3].callback(dyc_cbk_exti0_IRQ_hdr[3].param); // 调用回调函数并传递参数
    }
  }
}
void EXTI4_IRQHandler(void){
	if (EXTI_GetITStatus(EXTI_Line4)) {
		EXTI->IMR &= ~EXTI_Line4;
		EXTI_ClearITPendingBit(EXTI_Line4);
		if (dyc_cbk_exti0_IRQ_hdr[4].callback != NULL) {
			//printf("EXTI4_IRQHandler\r\n");
			dyc_cbk_exti0_IRQ_hdr[4].callback(dyc_cbk_exti0_IRQ_hdr[4].param); // 调用回调函数并传递参数
    }
  }
}
void EXTI9_5_IRQHandler(void){
	char *endptr_str,eli[2];
	unsigned int exti_line_i = 0;
	eli[0] = dyc_cbk_exti0_IRQ_hdr[5].param[0];
	exti_line_i = strtol(eli, &endptr_str, 10);
	if (EXTI_GetITStatus(exti_line[exti_line_i])) {
		EXTI->IMR &= ~exti_line[exti_line_i];
		EXTI_ClearITPendingBit(exti_line[exti_line_i]);
		if (dyc_cbk_exti0_IRQ_hdr[5].callback != NULL) {
			//printf("EXTI9_5_IRQHandler\r\n");
			dyc_cbk_exti0_IRQ_hdr[5].callback(dyc_cbk_exti0_IRQ_hdr[5].param + 2); // 调用回调函数并传递参数
    }
  }
}
void EXTI15_10_IRQHandler(void){
	char *endptr_str,eli[3];
	unsigned int exti_line_i = 0;
	eli[0] = dyc_cbk_exti0_IRQ_hdr[6].param[0];eli[1] = dyc_cbk_exti0_IRQ_hdr[6].param[1];
	exti_line_i = strtol(eli, &endptr_str, 10);
	if (EXTI_GetITStatus(exti_line[exti_line_i])) {
		EXTI->IMR &= ~exti_line[exti_line_i];
		EXTI_ClearITPendingBit(exti_line[exti_line_i]);
		if (dyc_cbk_exti0_IRQ_hdr[6].callback != NULL) {
			//printf("EXTI15_10_IRQHandler\r\n");
			dyc_cbk_exti0_IRQ_hdr[6].callback(dyc_cbk_exti0_IRQ_hdr[6].param + 3); // 调用回调函数并传递参数
    }
  }
}
void waitForInterrupt(char *xb){
	printf("waitForInterrupt|%s\r\n", xb);
	__WFI(); // 执行后CPU暂停并进入睡眠模式，低功耗，直到中断发生
}
void enableInterrupt(char *xb){
	char *endptr_str;
	unsigned int exti_line_i = 0;
	exti_line_i = strtol(xb, &endptr_str, 10);
	EXTI->IMR |= exti_line[exti_line_i]; // 重新使能EXTI1中断
	printf("enableInterrupt|%d\r\n",exti_line_i);
}
void delayS(char *xb){
		char *endptr_str;
    unsigned long seconds = strtoul(xb, &endptr_str, 10);
		unsigned int i = 0;    
    if (endptr_str == xb || *endptr_str != '\0' || seconds == 0 || seconds > 65535) {
        printf("delayS Invalid input! Use 1-65535 seconds\r\n");
        return;
    }
		printf("delayS|%lu\r\n",seconds);
		for(i=0;i<seconds;i++){
			delay_ms(1000);printf(".");
		}	
}


